#include "led_manager_adapter_espidf.h"

void digitalWriteWrapper(uint8_t pin, bool level) {
    gpio_set_level(pin, level ? 1 : 0);
}

uint32_t millisWrapper(void) {
    return esp_timer_get_time() / 1000;  // 转为毫秒
}

void pwmSetupWrapper(uint8_t pin, uint8_t channel) {
    ledc_timer_config_t ledc_timer = {
        .speed_mode       = LEDC_LOW_SPEED_MODE,
        .timer_num        = LEDC_TIMER_0,
        .duty_resolution  = LEDC_TIMER_8_BIT,
        .freq_hz          = 1000,
        .clk_cfg          = LEDC_AUTO_CLK,
    };
    ledc_timer_config(&ledc_timer);

    ledc_channel_config_t ledc_channel = {
        .gpio_num       = pin,
        .speed_mode     = LEDC_LOW_SPEED_MODE,
        .channel        = channel,
        .timer_sel      = LEDC_TIMER_0,
        .duty           = 0,
        .hpoint         = 0,
    };
    ledc_channel_config(&ledc_channel);
}

void pwmWriteWrapper(uint8_t pin, uint8_t duty) {
   LedState *leds = led_manager_get_all();
    for (size_t i = 0; i < led_manager_get_count(); i++)
    {
       if (leds[i].pin == pin)
       {
          ledc_set_duty(LEDC_LOW_SPEED_MODE, leds[i].pwmChannel, duty);
          ledc_update_duty(LEDC_LOW_SPEED_MODE, leds[i].pwmChannel);
          return;
       }
    }
}

void pwmDetachWrapper(uint8_t pin) {
    LedState *leds = led_manager_get_all();
    for (size_t i = 0; i < led_manager_get_count(); i++)
    {
       if (leds[i].pin == pin)
       {
          ledc_stop(LEDC_LOW_SPEED_MODE, leds[i].pwmChannel, 1);  // 重置为高
          return;
       }
    }
}

void addLedWithInit(uint8_t pin) {
    gpio_reset_pin(pin);
    gpio_set_direction(pin, GPIO_MODE_OUTPUT);
    led_manager_add(pin);
}

static void led_manager_timer_callback(void* arg) {
    led_manager_update();}

void startLedManagerTask(int delayMs) {
    led_manager_init(digitalWriteWrapper,millisWrapper,pwmSetupWrapper,pwmWriteWrapper,pwmDetachWrapper);
    const esp_timer_create_args_t timer_args = {
        .callback = &led_manager_timer_callback,
        .name = "led_mgr_timer"
    };
    esp_timer_handle_t timer;
    ESP_ERROR_CHECK(esp_timer_create(&timer_args, &timer));
    ESP_ERROR_CHECK(esp_timer_start_periodic(timer, delayMs * 1000));  // us
}